package main

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"
	"vconsole-go/websocket"
	"vconsolelib"

	ps "github.com/mitchellh/go-ps"
)

type Msg struct {
	Status int
	Text   string
}

var MsgOK = Msg{
	Status: 0,
	Text:   "OK",
}
var MsgDotaNotRuning = Msg{
	Status: 1,
	Text:   "Dota2 not runing",
}
var MsgNotConnect = Msg{
	Status: 2,
	Text:   "Connot connect to vconsole",
}
var MsgIsPlaying = Msg{
	Status: 3,
	Text:   "Is Playing this demo",
}
var MsgIsLoading = Msg{
	Status: 4,
	Text:   "Is Loading A Demo Now",
}
var MsgPlayFailed = Msg{
	Status: 5,
	Text:   "Play Demo Failed",
}
var MsgNotInGame = Msg{
	Status: 6,
	Text:   "Not In Game",
}
var MsgReadMsgErr = Msg{
	Status: 7,
	Text:   "Read Msg Err",
}
var Console, _ = vconsolelib.NewConsole()

func isDotaRuning() bool {
	proList, _ := ps.Processes()
	for _, pro := range proList {
		fmt.Println(pro.Executable())
		if pro.Executable() == "dota2.exe" {
			return true
		}
	}
	return false
}

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

//  Go build -ldflags="-H windowsgui" httpServer.go
func main() {
	http.HandleFunc("/cmd", Middleware(sendCmd))
	http.HandleFunc("/teamfight", Middleware(sendTeamFightCMD))
	http.HandleFunc("/playdemo", Middleware(sendPlayDemoCMD))
	err := http.ListenAndServe(":9099", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func Middleware(handler func(conn *websocket.Conn)) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		conn, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Println(err)
			return
		}
		if !isDotaRuning() {
			conn.WriteJSON(MsgDotaNotRuning)
			return
		}
		handler(conn)
		conn.Close()
	}
}
func sendCmd(conn *websocket.Conn) {
	_, message, err := conn.ReadMessage()
	if err != nil {
		log.Println("read:", err)
		conn.WriteJSON(MsgReadMsgErr)
		return
	}
	log.Printf("recv: %s", message)
	if ok := Console.SendCmd(string(message)); !ok {
		conn.WriteJSON(MsgNotConnect)
		return
	}
	conn.WriteJSON(MsgOK)
}
func sendPlayDemoCMD(conn *websocket.Conn) {
	_, message, err := conn.ReadMessage()
	if err != nil {
		log.Println("read:", err)
		conn.WriteJSON(MsgReadMsgErr)
		return
	}
	log.Printf("recv: %s", message)
	matchID := string(message)
	if Console.Lib != nil {
		fmt.Println("uiStatus", Console.Lib.UIStatus)
		switch Console.Lib.UIStatus {
		case vconsolelib.DOTA_GAME_UI_STATE_LOADING_SCREEN, vconsolelib.DOTA_GAME_UI_DOTA_INGAME:
			conn.WriteJSON(MsgIsLoading)
			return
		case vconsolelib.DOTA_GAME_UI_DOTA_HeroSelect:
			if matchID == Console.Lib.Replay {
				conn.WriteJSON(MsgIsPlaying)
				return
			}
		default:
		}
	}
	if ok := Console.Playdemo(matchID); !ok {
		conn.WriteJSON(MsgNotConnect)
		return
	}
	select {
	case <-time.After(2 * time.Second):
		break
	case <-Console.Lib.PlayFailed:
		conn.WriteJSON(MsgPlayFailed)
		return
	}
	for Console.Lib.UIStatus != vconsolelib.DOTA_GAME_UI_DOTA_HeroSelect {
		fmt.Println(Console.Lib.UIStatus)
	}
	conn.WriteJSON(MsgOK)
}

// 需要参数startTick,endTick
func sendTeamFightCMD(conn *websocket.Conn) {
	_, message, err := conn.ReadMessage()
	if err != nil {
		log.Println("read:", err)
		conn.WriteJSON(MsgReadMsgErr)
		return
	}
	log.Printf("recv: %s", message)
	if Console.Lib == nil || Console.Lib.UIStatus != vconsolelib.DOTA_GAME_UI_DOTA_HeroSelect {
		conn.WriteJSON(MsgNotInGame)
		return
	}
	startTick, _ := strconv.Atoi(string(message))
	// endTick, _ := strconv.Atoi(r.FormValue("endTick"))
	if ok := Console.SkipToTick(uint32(startTick)); !ok {
		conn.WriteJSON(MsgNotConnect)
		return
	}
	if ok := Console.SetDirectedCamera(); !ok {
		conn.WriteJSON(MsgNotConnect)
		return
	}
	conn.WriteJSON(MsgOK)
}
